package top.codef.secure.login;

import java.util.Collection;
import java.util.Map;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.userdetails.UserDetails;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonDeserialize(using = CerberusAuthenticationTokenDeserializer.class)
public class CerberusAuthenticationToken extends AbstractAuthenticationToken {

	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

	private final Object principal;

	private Object credentials;

	private String optional;

	private Map<String, Object> additionalParams;

	public CerberusAuthenticationToken(Object principal, Object credentials, String optional,
			Map<String, Object> additionalParams) {
		super(null);
		this.principal = principal;
		this.credentials = credentials;
		this.additionalParams = additionalParams;
		this.optional = optional;
		setAuthenticated(false);
	}

	public CerberusAuthenticationToken(UserDetails userDetails,
			CerberusAuthenticationToken cerberusAuthenticationToken) {
		super(userDetails.getAuthorities());
		this.optional = cerberusAuthenticationToken.getOptional();
		this.principal = userDetails;
		this.credentials = cerberusAuthenticationToken.getCredentials();
		setAuthenticated(true);
	}

	public CerberusAuthenticationToken(Object principal, Object credentials, String optional,
			Collection<? extends GrantedAuthority> authorities, Map<String, Object> additionalParams) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		this.additionalParams = additionalParams;
		this.optional = optional;
		setAuthenticated(true);
	}

	@Override
	public Object getCredentials() {
		return credentials;
	}

	@Override
	public Object getPrincipal() {
		return principal;
	}

	public Map<String, Object> getAdditionalParams() {
		return additionalParams;
	}

	public void setAdditionalParams(Map<String, Object> additionalParams) {
		this.additionalParams = additionalParams;
	}

	public String getOptional() {
		return optional;
	}

	public void setOptional(String optional) {
		this.optional = optional;
	}

}
